/**
 * 手写Promise实现 - 符合Promise/A+规范的简化版本
 * Promise是一种异步编程解决方案，用于处理异步操作的结果
 */

// Promise的三种状态
const PENDING = 'pending';    // 等待中
const FULFILLED = 'fulfilled'; // 已成功
const REJECTED = 'rejected';   // 已失败

class MyPromise {
  /**
   * Promise构造函数
   * @param {Function} executor - 执行器函数，接收resolve和reject两个参数
   */
  constructor(executor) {
    // 初始化状态为等待中
    this.status = PENDING;
    // 存储成功的值
    this.value = null;
    // 存储失败的原因
    this.reason = null;
    // 存储成功回调函数队列
    this.onFulfilledCallbacks = [];
    // 存储失败回调函数队列
    this.onRejectedCallbacks = [];
    
    /**
     * 将Promise状态从pending改为fulfilled
     * @param {*} value - 成功的值
     */
    const resolve = (value) => {
      // 只有在pending状态下才能改变为fulfilled状态
      if (this.status === PENDING) {
        this.status = FULFILLED;
        this.value = value;
        // 依次执行所有成功回调
        this.onFulfilledCallbacks.forEach(callback => callback());
      }
    };
    
    /**
     * 将Promise状态从pending改为rejected
     * @param {*} reason - 失败的原因
     */
    const reject = (reason) => {
      // 只有在pending状态下才能改变为rejected状态
      if (this.status === PENDING) {
        this.status = REJECTED;
        this.reason = reason;
        // 依次执行所有失败回调
        this.onRejectedCallbacks.forEach(callback => callback());
      }
    };
    
    // 执行executor函数，捕获可能的错误
    try {
      executor(resolve, reject);
    } catch (error) {
      // 如果执行器抛出错误，直接reject
      reject(error);
    }
  }
  
  /**
   * Promise的then方法
   * @param {Function} onFulfilled - 成功时的回调函数
   * @param {Function} onRejected - 失败时的回调函数
   * @returns {MyPromise} - 返回一个新的Promise实例，用于链式调用
   */
  then(onFulfilled, onRejected) {
    // 处理参数可能不是函数的情况
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };
    
    // 创建一个新的Promise实例用于链式调用
    const promise2 = new MyPromise((resolve, reject) => {
      // 处理FULFILLED状态
      if (this.status === FULFILLED) {
        // 使用setTimeout模拟异步执行，确保onFulfilled/onRejected异步执行
        setTimeout(() => {
          try {
            // 执行成功回调，并获取返回值
            const x = onFulfilled(this.value);
            // 处理返回值，确保链式调用的正确性
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            // 如果回调执行出错，直接reject
            reject(error);
          }
        }, 0);
      }
      
      // 处理REJECTED状态
      if (this.status === REJECTED) {
        setTimeout(() => {
          try {
            // 执行失败回调，并获取返回值
            const x = onRejected(this.reason);
            // 处理返回值
            resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      }
      
      // 处理PENDING状态
      if (this.status === PENDING) {
        // 将回调函数存储到对应队列中，等待状态改变时执行
        this.onFulfilledCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onFulfilled(this.value);
              resolvePromise(promise2, x, resolve, reject);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });
        
        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onRejected(this.reason);
              resolvePromise(promise2, x, resolve, reject);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });
      }
    });
    
    return promise2;
  }
  
  /**
   * Promise的catch方法
   * @param {Function} onRejected - 失败时的回调函数
   * @returns {MyPromise} - 返回一个新的Promise实例
   */
  catch(onRejected) {
    return this.then(null, onRejected);
  }
  
  /**
   * Promise的finally方法
   * @param {Function} onFinally - 无论成功或失败都会执行的回调函数
   * @returns {MyPromise} - 返回一个新的Promise实例
   */
  finally(onFinally) {
    return this.then(
      value => MyPromise.resolve(onFinally()).then(() => value),
      reason => MyPromise.resolve(onFinally()).then(() => { throw reason; })
    );
  }
  
  /**
   * Promise的静态resolve方法
   * @param {*} value - 要解析为Promise的值
   * @returns {MyPromise} - 返回一个已解析的Promise
   */
  static resolve(value) {
    // 如果value已经是MyPromise实例，直接返回
    if (value instanceof MyPromise) {
      return value;
    }
    // 否则创建一个新的Promise并立即resolve
    return new MyPromise((resolve, reject) => {
      resolve(value);
    });
  }
  
  /**
   * Promise的静态reject方法
   * @param {*} reason - 拒绝的原因
   * @returns {MyPromise} - 返回一个已拒绝的Promise
   */
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }
  
  /**
   * Promise的静态all方法
   * @param {Array} promises - Promise数组
   * @returns {MyPromise} - 当所有Promise都成功时才成功，否则失败
   */
  static all(promises) {
    return new MyPromise((resolve, reject) => {
      // 存储所有Promise的结果
      const results = [];
      // 计数器，用于跟踪已完成的Promise数量
      let count = 0;
      
      // 处理数组为空的情况
      if (promises.length === 0) {
        resolve(results);
        return;
      }
      
      // 遍历所有Promise
      for (let i = 0; i < promises.length; i++) {
        // 使用resolve处理每个元素，确保它是Promise
        MyPromise.resolve(promises[i]).then(
          value => {
            // 存储结果到对应位置
            results[i] = value;
            // 计数器加1
            count++;
            // 如果所有Promise都已完成，resolve结果数组
            if (count === promises.length) {
              resolve(results);
            }
          },
          reason => {
            // 如果有任何一个Promise失败，立即reject
            reject(reason);
          }
        );
      }
    });
  }
  
  /**
   * Promise的静态race方法
   * @param {Array} promises - Promise数组
   * @returns {MyPromise} - 返回第一个完成的Promise的结果（无论成功或失败）
   */
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      // 遍历所有Promise
      for (let i = 0; i < promises.length; i++) {
        // 一旦有任何一个Promise完成，就立即返回其结果
        MyPromise.resolve(promises[i]).then(
          value => resolve(value),
          reason => reject(reason)
        );
      }
    });
  }
  
  /**
   * Promise的静态allSettled方法
   * @param {Array} promises - Promise数组
   * @returns {MyPromise} - 返回所有Promise的结果，无论成功或失败
   */
  static allSettled(promises) {
    return new MyPromise((resolve) => {
      // 存储所有Promise的结果
      const results = [];
      // 计数器
      let count = 0;
      
      // 处理空数组
      if (promises.length === 0) {
        resolve(results);
        return;
      }
      
      // 遍历所有Promise
      for (let i = 0; i < promises.length; i++) {
        MyPromise.resolve(promises[i]).then(
          value => {
            results[i] = { status: FULFILLED, value };
            count++;
            if (count === promises.length) {
              resolve(results);
            }
          },
          reason => {
            results[i] = { status: REJECTED, reason };
            count++;
            if (count === promises.length) {
              resolve(results);
            }
          }
        );
      }
    });
  }
  
  /**
   * Promise的静态any方法
   * @param {Array} promises - Promise数组
   * @returns {MyPromise} - 只要有一个Promise成功就返回其结果，如果所有都失败则返回AggregateError
   */
  static any(promises) {
    return new MyPromise((resolve, reject) => {
      // 存储所有失败的原因
      const errors = [];
      // 计数器
      let count = 0;
      
      // 处理空数组
      if (promises.length === 0) {
        reject(new AggregateError([], 'All promises were rejected'));
        return;
      }
      
      // 遍历所有Promise
      for (let i = 0; i < promises.length; i++) {
        MyPromise.resolve(promises[i]).then(
          value => {
            // 只要有一个成功，就立即resolve
            resolve(value);
          },
          reason => {
            errors[i] = reason;
            count++;
            // 如果所有Promise都失败了，reject一个AggregateError
            if (count === promises.length) {
              reject(new AggregateError(errors, 'All promises were rejected'));
            }
          }
        );
      }
    });
  }
}

/**
 * 处理Promise链式调用中的返回值
 * @param {MyPromise} promise2 - then方法返回的新Promise
 * @param {*} x - 回调函数的返回值
 * @param {Function} resolve - promise2的resolve方法
 * @param {Function} reject - promise2的reject方法
 */
function resolvePromise(promise2, x, resolve, reject) {
  // 如果x就是promise2，抛出TypeError（防止循环引用）
  if (promise2 === x) {
    return reject(new TypeError('Chaining cycle detected for promise'));
  }
  
  // 标记是否已经调用过resolve或reject
  let called = false;
  
  // 如果x是对象或函数
  if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
    try {
      // 获取then方法
      const then = x.then;
      // 如果then是函数，将x视为Promise
      if (typeof then === 'function') {
        // 调用then方法，传入resolvePromise和rejectPromise作为参数
        then.call(
          x,
          // 如果x成功，递归调用resolvePromise
          y => {
            // 确保只调用一次
            if (called) return;
            called = true;
            resolvePromise(promise2, y, resolve, reject);
          },
          // 如果x失败，直接reject
          r => {
            if (called) return;
            called = true;
            reject(r);
          }
        );
      } else {
        // 如果then不是函数，直接resolve(x)
        resolve(x);
      }
    } catch (error) {
      // 如果获取then或调用then时出错，直接reject
      if (called) return;
      called = true;
      reject(error);
    }
  } else {
    // 如果x不是对象或函数，直接resolve(x)
    resolve(x);
  }
}

// 测试代码
console.log('=== 手写Promise测试 ===');

// 测试基本功能
console.log('--- 测试基本功能 ---');
const promise1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功了！');
  }, 1000);
});

promise1.then(
  value => console.log('成功:', value),
  reason => console.log('失败:', reason)
);

// 测试链式调用
console.log('\n--- 测试链式调用 ---');
const promise2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 1000);
});

promise2
  .then(value => {
    console.log('第一步:', value);
    return value + 1;
  })
  .then(value => {
    console.log('第二步:', value);
    return value + 1;
  })
  .then(value => {
    console.log('第三步:', value);
  });

// 测试静态方法
console.log('\n--- 测试静态方法 ---');

// 测试MyPromise.resolve
MyPromise.resolve('直接成功').then(value => {
  console.log('resolve方法:', value);
});

// 测试MyPromise.reject
MyPromise.reject('直接失败').catch(reason => {
  console.log('reject方法:', reason);
});

// 测试MyPromise.all
setTimeout(() => {
  console.log('\n--- 测试MyPromise.all ---');
  const promise3 = MyPromise.resolve(1);
  const promise4 = new MyPromise((resolve) => setTimeout(() => resolve(2), 500));
  const promise5 = new MyPromise((resolve) => setTimeout(() => resolve(3), 1000));
  
  MyPromise.all([promise3, promise4, promise5]).then(values => {
    console.log('all方法结果:', values); // 应该输出 [1, 2, 3]
  });
}, 3000);

// 测试MyPromise.race
setTimeout(() => {
  console.log('\n--- 测试MyPromise.race ---');
  const promise6 = new MyPromise((resolve) => setTimeout(() => resolve(1), 1000));
  const promise7 = new MyPromise((resolve) => setTimeout(() => resolve(2), 500));
  const promise8 = new MyPromise((resolve) => setTimeout(() => resolve(3), 1500));
  
  MyPromise.race([promise6, promise7, promise8]).then(value => {
    console.log('race方法结果:', value); // 应该输出 2
  });
}, 5000);

// 测试finally方法
console.log('\n--- 测试finally方法 ---');
new MyPromise((resolve) => setTimeout(() => resolve('finally测试'), 2000))
  .then(value => console.log('finally前:', value))
  .finally(() => console.log('finally执行了'))
  .then(() => console.log('finally后'));

// 模拟AggregateError类（在不支持的环境中）
if (typeof AggregateError === 'undefined') {
  class AggregateError extends Error {
    constructor(errors, message) {
      super(message);
      this.name = 'AggregateError';
      this.errors = errors;
    }
  }
  global.AggregateError = AggregateError;
}

/**
 * Promise相关知识总结：
 * 
 * 1. Promise的三种状态：
 *    - pending: 初始状态，既不是成功也不是失败
 *    - fulfilled: 操作成功完成
 *    - rejected: 操作失败
 * 
 * 2. Promise的特点：
 *    - 状态一旦改变，就不能再变
 *    - 链式调用可以避免回调地狱
 *    - 提供了统一的异步错误处理机制
 * 
 * 3. 常用方法：
 *    - then: 添加成功和失败的回调
 *    - catch: 添加失败的回调
 *    - finally: 添加无论成功或失败都会执行的回调
 *    - resolve: 返回一个已成功的Promise
 *    - reject: 返回一个已失败的Promise
 *    - all: 等待所有Promise完成
 *    - race: 返回第一个完成的Promise的结果
 *    - allSettled: 返回所有Promise的结果，无论成功或失败
 *    - any: 返回第一个成功的Promise的结果
 * 
 * 4. Promise/A+规范的核心要点：
 *    - 状态不可逆
 *    - then方法必须返回新的Promise
 *    - then方法支持链式调用
 *    - 必须处理Promise的返回值
 *    - 错误冒泡机制
 */